package main

import "fmt"

func foo1() {
	for i := 0; i <= 3; i++ {
		// defer 语句执行时，会把需要延迟调用的函数和参数保存起来
		defer fmt.Println(i) // 此函数的调用被推入延迟调用堆栈时i就已经估值了
		// 3, 2, 1, 0
	}
}

func foo2() {
	for i := 0; i <= 3; i++ {
		defer func(n int) {
			fmt.Println(n)
		}(i)

		// 3,2,1,0
	}
}

func foo3() {
	for i := 0; i <= 3; i++ {
		// 不带参数的匿名函数
		// 以闭包的形式访问外围变量
		defer func() {
			fmt.Println(i) // i 是在匿名函数调用退出阶段估值的
		}()
		// 4 4 4 4
	}
}

func main() {
	fmt.Println("foo1 result:")
	foo1()
	fmt.Println("\nfoo2 result:")
	foo2()
	fmt.Println("\nfoo3 result:")
	foo3()
}
